package com.siteseat.common.collection;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 *
 */
public class SinceList<E> implements Iterable<E> {

  private List<E>             elements;

  private Map<E, Iterator<E>> segments;

  /**
   * @param elements
   * @param since
   */
  public SinceList( List<E> listContainer, Map<E, Iterator<E>> mapContainer ) {
    assert listContainer != null;
    this.elements = listContainer;

    assert mapContainer != null;
    this.segments = mapContainer;
  }

  /**
   * 
   *
   *
   */
  public SinceList( Map<E, Iterator<E>> mapContainer ) {
    this( new ArrayList<E>(), mapContainer );
  }

  /**
   * 
   *
   *
   */
  public SinceList( List<E> listContainer ) {
    this( listContainer, new HashMap<E, Iterator<E>>() );
  }

  /**
   * 
   *
   *
   */
  public SinceList() {
    this( new ArrayList<E>(), new HashMap<E, Iterator<E>>() );
  }

  /**
   * @param newElement
   */
  public void add( E newElement ) {
    this.elements.add( newElement );
    this.segments.put( newElement, this.elements.listIterator( this.elements.size() - 1 ) );
  }

  /**
   * @param since
   * @return
   */
  public Iterator<E> sinceExcluded( E since ) {
    Iterator<E> r = this.segments.get( since );
    if( r.hasNext() == false ) {
      return null;
    }
    r.next();
    return r;
  }

  /**
   * @param since
   * @return
   */
  public Iterator<E> sinceIncluded( E since ) {
    Iterator<E> r = this.segments.get( since );
    if( r.hasNext() == false ) {
      return null;
    }
    return r;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Iterator<E> iterator() {
    return elements.iterator();
  }
}
